package es.uc3m.setichat.utils;

import java.util.ArrayList;
import java.util.Random;

import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Text;
import com.google.appengine.api.xmpp.JID;
import com.google.appengine.api.xmpp.Message;
import com.google.appengine.api.xmpp.MessageBuilder;
import com.google.appengine.api.xmpp.MessageType;

import es.uc3m.setichat.appengine.servlets.CreateSetiChatMessageException;
import es.uc3m.setichat.appengine.servlets.XmppReceiverServlet;
import es.uc3m.setichat.constants.DataModelConstants;
import es.uc3m.setichat.constants.ErrorConstants;
import es.uc3m.setichat.constants.GeneralConstants;
import es.uc3m.setichat.constants.MessageTypeConstants;
import es.uc3m.setichat.constants.ResponseMessageConstants;
import es.uc3m.setichat.constants.TypeCertificationConstants;
import es.uc3m.setichat.utils.setichatxmlschema.SetiChatMessage;
import es.uc3m.setichat.utils.setichatxmlschema.SetiChatMessage.Header;
import es.uc3m.setichat.utils.setichatxmlschema.SetiChatMessageFactory;

/**
 * Each action is a response for a type o SetiChat message.
 * */

public class ServerActions {

	/**
	 * Method to make a certificate public key.
	 * 
	 * @param setiChatMessage
	 *            message received to be processed
	 * @return scXmlResponse string with xml response. It is ready to send to
	 *         client.
	 * */
	public static String doCertificateRequest(SetiChatMessage setiChatMessage) {
		boolean isPermitted = true;
		boolean isPublicKey = false;
		String scXmlResponse = new String();
		String cert = new String();
		String typeCert = setiChatMessage.getContent().getCertificaterequest()
				.getType();
		String mobile = setiChatMessage.getContent().getCertificaterequest()
				.getMobile();
		// Check if public key or private key.
		if (typeCert
				.compareToIgnoreCase(TypeCertificationConstants.TYPE_CERT_CER) == 0) {
			cert = SecurityManager.getCertification(mobile, typeCert);
			isPublicKey = true;

		} else if (typeCert
				.compareToIgnoreCase(TypeCertificationConstants.TYPE_CERT_P12) == 0) {
			// Private key is allowed for owner.
			if (mobile.compareToIgnoreCase(setiChatMessage.getHeader()
					.getIdSource()) == 0) {
				cert = SecurityManager.getCertification(mobile, typeCert);
				isPublicKey = false;
			} else {
				isPermitted = false;
			}
		}
		// Download permitted
		if (isPermitted) {
			// if cert is empty, there isn't the cert of this user.
			if (!cert.isEmpty()) {
				SetiChatMessageFactory scMessageResponse = new SetiChatMessageFactory();
				scXmlResponse = scMessageResponse
						.createSetiChatMessageDownload(
								GeneralConstants.SELF,
								setiChatMessage.getHeader().getIdSource(),
								setiChatMessage.getHeader().getIdMessage(),
								String.valueOf(MessageTypeConstants.TYPE_DOWNLOAD),
								setiChatMessage.getHeader().isEncrypted(),
								setiChatMessage.getHeader().isSigned(), cert,
								typeCert, mobile);
			} else {
				// Sending correct error message.
				if (isPublicKey) {
					SetiChatMessageFactory scMessageResponse = new SetiChatMessageFactory();
					scXmlResponse = scMessageResponse
							.createSetiChatMessageResponse(
									GeneralConstants.SELF,
									setiChatMessage.getHeader().getIdSource(),
									setiChatMessage.getHeader().getIdMessage(),
									String.valueOf(MessageTypeConstants.TYPE_RESPONSE),
									setiChatMessage.getHeader().isEncrypted(),
									setiChatMessage.getHeader().isSigned(),
									ErrorConstants.ERROR_CODE_CER_NOT_FOUND,
									ErrorConstants.ERROR_MESSAGE_CER_NOT_FOUND);
				} else {
					SetiChatMessageFactory scMessageResponse = new SetiChatMessageFactory();
					scXmlResponse = scMessageResponse
							.createSetiChatMessageResponse(
									GeneralConstants.SELF,
									setiChatMessage.getHeader().getIdSource(),
									setiChatMessage.getHeader().getIdMessage(),
									String.valueOf(MessageTypeConstants.TYPE_RESPONSE),
									setiChatMessage.getHeader().isEncrypted(),
									setiChatMessage.getHeader().isSigned(),
									ErrorConstants.ERROR_CODE_P12_NOT_FOUND,
									ErrorConstants.ERROR_MESSAGE_P12_NOT_FOUND);
				}
			}
		} else {
			// Sending error id try download a private key.
			SetiChatMessageFactory scMessageResponse = new SetiChatMessageFactory();
			scXmlResponse = scMessageResponse.createSetiChatMessageResponse(
					GeneralConstants.SELF, setiChatMessage.getHeader()
							.getIdSource(), setiChatMessage.getHeader()
							.getIdMessage(), String
							.valueOf(MessageTypeConstants.TYPE_RESPONSE),
					setiChatMessage.getHeader().isEncrypted(), setiChatMessage
							.getHeader().isSigned(),
					ErrorConstants.ERROR_CODE_NOT_PERMITTED,
					ErrorConstants.ERROR_MESSAGE_NOT_PERMITTED);
		}
		return scXmlResponse;
	}

	/**
	 * Method to make a response to chat message.
	 * 
	 * @param setiChatMessage
	 *            message received to be processed
	 * @return scXmlResponse string with xml response. It is ready to send to
	 *         client.
	 * */
	public static String doChatMessage(SetiChatMessage setiChatMessage) {
		String scXmlResponse = new String();
		SetiChatMessageFactory scMessageResponse = new SetiChatMessageFactory();
		scXmlResponse = scMessageResponse.createSetiChatMessageResponse(
				GeneralConstants.SELF, setiChatMessage.getHeader()
						.getIdSource(), setiChatMessage.getHeader()
						.getIdMessage(), String
						.valueOf(MessageTypeConstants.TYPE_CHATMESSAGE),
				setiChatMessage.getHeader().isEncrypted(), setiChatMessage
						.getHeader().isSigned(),
				ResponseMessageConstants.RESPONSE_CODE_CHATMESSAGE_OK,
				ResponseMessageConstants.RESPONSE_MESSAGE_CHATMESSAGE_OK);
		return scXmlResponse;
	}

	/**
	 * Method to make a response to connection message.
	 * 
	 * @param setiChatMessage
	 *            message received to be processed
	 * @return scXmlResponse string with xml response. It is ready to send to
	 *         client.
	 * */
	public static String doConnection(SetiChatMessage setiChatMessage) {
		Query queryConnection = new Query(DataModelConstants.DS_ENTITY_USER);
		XmppReceiverServlet.log.warning(setiChatMessage.getHeader()
				.getIdSource());
		queryConnection.addFilter(DataModelConstants.DS_PROPERTY_USER_MOBILE,
				Query.FilterOperator.EQUAL, setiChatMessage.getHeader()
						.getIdSource());
		PreparedQuery pq = XmppReceiverServlet.datastore
				.prepare(queryConnection);
		String scXmlResponse = new String();
		if (pq.asList(FetchOptions.Builder.withDefaults()).size() == 1) {
			SetiChatMessageFactory scMessageResponse = new SetiChatMessageFactory();
			scXmlResponse = scMessageResponse.createSetiChatMessageResponse(
					GeneralConstants.SELF, setiChatMessage.getHeader()
							.getIdSource(), setiChatMessage.getHeader()
							.getIdMessage(), String
							.valueOf(MessageTypeConstants.TYPE_RESPONSE),
					setiChatMessage.getHeader().isEncrypted(), setiChatMessage
							.getHeader().isSigned(),
					ResponseMessageConstants.RESPONSE_CODE_CONNECTION_OK,
					ResponseMessageConstants.RESPONSE_MESSAGE_CONNECTION_OK);
		} else {
			scXmlResponse = doErrorMessage(setiChatMessage,
					ErrorConstants.ERROR_CODE_USER_NOT_PRESENT,
					ErrorConstants.ERROR_MESSAGE_USER_NOT_PRESENT);
		}
		return scXmlResponse;
	}

	/**
	 * Method to make contacts request.
	 * 
	 * @param setiChatMessage
	 *            message received to be processed
	 * @return scXmlResponse string with xml response. It is ready to send to
	 *         client.
	 * */
	public static String doContactRequest(SetiChatMessage setiChatMessage) {
		String scXmlResponse = new String();
		Query queryUser = new Query(DataModelConstants.DS_ENTITY_USER);
		ArrayList<String> mobilContact = (ArrayList<String>) setiChatMessage
				.getContent().getMobileList().getMobile();
		ArrayList<String> nickUsers = new ArrayList<String>();
		ArrayList<String> mobilUsers = new ArrayList<String>();
		PreparedQuery pq;
		String user = setiChatMessage.getHeader().getIdSource();
		Entity contacts = new Entity(DataModelConstants.DS_ENTITY_CONTACTS,
				user);
		for (int i = 0; i < mobilContact.size(); i++) {
			queryUser.addFilter(DataModelConstants.DS_PROPERTY_USER_MOBILE,
					Query.FilterOperator.EQUAL, mobilContact.get(i));
			pq = XmppReceiverServlet.datastore.prepare(queryUser);
			for (Entity result : pq.asIterable()) {
				String nickUser = (String) result
						.getProperty(DataModelConstants.DS_PROPERTY_USER_NICK);
				String mobilUser = (String) result
						.getProperty(DataModelConstants.DS_PROPERTY_USER_MOBILE);
				nickUsers.add(nickUser);
				mobilUsers.add(mobilUser);
				contacts.setProperty(
						DataModelConstants.DS_PROPERTY_CONTACTS_CONTACTX + i,
						mobilUser);
				contacts.setProperty(
						DataModelConstants.DS_PROPERTY_CONTACTS_NUMCONTACTS, i);
			}
			queryUser = new Query(DataModelConstants.DS_ENTITY_USER);
		}
		XmppReceiverServlet.datastore.put(contacts);
		SetiChatMessageFactory scMessageResponse = new SetiChatMessageFactory();
		scXmlResponse = scMessageResponse.createSetiChatMessageContactResponse(
				GeneralConstants.SELF, setiChatMessage.getHeader()
						.getIdSource(), setiChatMessage.getHeader()
						.getIdMessage(), String
						.valueOf(MessageTypeConstants.TYPE_CONTACTRESPONSE),
				setiChatMessage.getHeader().isEncrypted(), setiChatMessage
						.getHeader().isSigned(), mobilUsers, nickUsers);
		return scXmlResponse;
	}

	/**
	 * Method to make a error message. Recommended for messages without form.
	 * 
	 * @param setiChatMessageHeader
	 *            header of the message received to be processed
	 * @param errorCode
	 *            Code of the error message
	 * @param errorMessage
	 *            Message of the error message
	 * @return scXmlResponse string with xml response. It is ready to send to
	 *         client.
	 * */
	public static String doErrorMessage(Header setiChatMessageHeader,
			String responseCode, String responseMessage) {
		String scXmlResponse = new String();
		SetiChatMessageFactory scMessageResponse = new SetiChatMessageFactory();
		scXmlResponse = scMessageResponse
				.createSetiChatMessageResponse(
						setiChatMessageHeader.getIdSource(),
						GeneralConstants.SELF,
						setiChatMessageHeader.getIdMessage(),
						String.valueOf(MessageTypeConstants.TYPE_RESPONSE),
						setiChatMessageHeader.isEncrypted(),
						setiChatMessageHeader.isSigned(), responseCode,
						responseMessage);
		return scXmlResponse;
	}

	/**
	 * Method to make a error message.
	 * 
	 * @param setiChatMessage
	 *            message received to be processed
	 * @param errorCode
	 *            Code of the error message
	 * @param errorMessage
	 *            Message of the error message
	 * @return scXmlResponse string with xml response. It is ready to send to
	 *         client.
	 * */
	public static String doErrorMessage(SetiChatMessage setiChatMessage,
			String errorCode, String errorMessage) {
		String scXmlResponse = new String();
		SetiChatMessageFactory scMessageResponse = new SetiChatMessageFactory();
		scXmlResponse = scMessageResponse.createSetiChatMessageResponse(
				GeneralConstants.SELF, setiChatMessage.getHeader()
						.getIdSource(), setiChatMessage.getHeader()
						.getIdMessage(), String
						.valueOf(MessageTypeConstants.TYPE_RESPONSE),
				setiChatMessage.getHeader().isEncrypted(), setiChatMessage
						.getHeader().isSigned(), errorCode, errorMessage);
		return scXmlResponse;
	}

	/**
	 * Method to make a response to revokation message.
	 * 
	 * @param setiChatMessage
	 *            message received to be processed
	 * @return scXmlResponse string with xml response. It is ready to send to
	 *         client.
	 * */
	public static String doRevocationMessage(SetiChatMessage setiChatMessage) {
		String scXmlResponse = new String();
		String mobile = setiChatMessage.getHeader().getIdSource();

		SecurityManager.broadcastRevocation(mobile);

		SetiChatMessageFactory scMessageRevocation = new SetiChatMessageFactory();
		scXmlResponse = scMessageRevocation.createSetiChatMessageResponse(
				GeneralConstants.SELF, setiChatMessage.getHeader()
						.getIdSource(), setiChatMessage.getHeader()
						.getIdMessage(), String
						.valueOf(MessageTypeConstants.TYPE_RESPONSE),
				setiChatMessage.getHeader().isEncrypted(), setiChatMessage
						.getHeader().isSigned(),
				ResponseMessageConstants.RESPONSE_CODE_UPLOAD_REVOCATION_OK,
				ResponseMessageConstants.RESPONSE_MESSAGE_UPLOAD_REVOCATION_OK);
		return scXmlResponse;
	}

	/**
	 * Method to send pending message to idDestination
	 * 
	 * @param idDestination
	 *            ID of the user who has made connection
	 * @return Number of the message sent.
	 * */
	public static int doSendPendingMessage(String idDestination) {
		int count = 0;
		Query queryPendingMessage = new Query(
				DataModelConstants.DS_ENTITY_PENDIGMESSAGE);
		PreparedQuery pq;
		queryPendingMessage.addFilter(
				DataModelConstants.DS_PROPERTY_PENDIGMESSAGE_IDDESTINATION,
				Query.FilterOperator.EQUAL, idDestination);
		pq = XmppReceiverServlet.datastore.prepare(queryPendingMessage);
		String pendingMessage = new String();
		SetiChatMessage setiChatMessage = new SetiChatMessage();
		Text textPendingMessage = null;
		for (Entity result : pq.asIterable()) {
			textPendingMessage = (Text) (result
					.getProperty(DataModelConstants.DS_PROPERTY_PENDIGMESSAGE_MESSAGE));
			pendingMessage = textPendingMessage.getValue();
			try {
				setiChatMessage = XmppReceiverServlet.setiChatMessageFactory
						.createSetiChatMessage(pendingMessage);
				sendToMessage(setiChatMessage);
				XmppReceiverServlet.datastore.delete(result.getKey());
				count++;
			} catch (CreateSetiChatMessageException e) {
				XmppReceiverServlet.log
						.warning(ErrorConstants.ERROR_MESSAGE_WRONG_FORMAT);
			}
		}

		return count;
	}

	/**
	 * Method do SignUp operation.
	 * 
	 * @param setiChatMessage
	 *            message received to be processed
	 * @param emailSource
	 *            email of source
	 * @return scXmlResponse string with xml response. It is ready to send to
	 *         client.
	 * */
	public static String doSignUp(SetiChatMessage setiChatMessage,
			String emailSource) {
		Query querySignup = new Query(DataModelConstants.DS_ENTITY_USER);
		querySignup.addFilter(DataModelConstants.DS_PROPERTY_USER_MOBILE,
				Query.FilterOperator.EQUAL, setiChatMessage.getContent()
						.getSignup().getMobile());
		PreparedQuery pq;
		pq = XmppReceiverServlet.datastore.prepare(querySignup);
		String scXmlResponse = new String();
		if (pq.asList(FetchOptions.Builder.withDefaults()).size() < 1) {
			// User Entity with googleID as key
			Entity user = new Entity(DataModelConstants.DS_ENTITY_USER,
					emailSource);
			// propieties User
			// user nickname from signup message
			user.setProperty(DataModelConstants.DS_PROPERTY_USER_NICK,
					setiChatMessage.getContent().getSignup().getNick());
			// user mobile number from signup message
			user.setProperty(DataModelConstants.DS_PROPERTY_USER_MOBILE,
					setiChatMessage.getContent().getSignup().getMobile());
			// stored in datastore
			XmppReceiverServlet.datastore.put(user);

			// Log stored user
			XmppReceiverServlet.log.warning("[GoogleID:" + emailSource
					+ "\tNick:"
					+ setiChatMessage.getContent().getSignup().getNick()
					+ "\tMobile:"
					+ setiChatMessage.getContent().getSignup().getMobile()
					+ "]");
			// Seti chat Message response
			SetiChatMessageFactory scMessageResponse = new SetiChatMessageFactory();
			scXmlResponse = scMessageResponse.createSetiChatMessageResponse(
					GeneralConstants.SELF, setiChatMessage.getHeader()
							.getIdSource(), setiChatMessage.getHeader()
							.getIdMessage(), String
							.valueOf(MessageTypeConstants.TYPE_RESPONSE),
					setiChatMessage.getHeader().isEncrypted(), setiChatMessage
							.getHeader().isSigned(),
					ResponseMessageConstants.RESPONSE_CODE_SIGNUP_OK,
					ResponseMessageConstants.RESPONSE_MESSAGE_SIGNUP_OK);
		} else {
			scXmlResponse = doErrorMessage(setiChatMessage,
					ErrorConstants.ERROR_CODE_MOBILE_PRESENT,
					ErrorConstants.ERROR_MESSAGE_MOBILE_PRESENT);
		}
		return scXmlResponse;
	}

	/**
	 * Method to store a message when user destination is not available.
	 * 
	 * @param setiChatMessage
	 *            message received to be processed
	 * @return scXmlResponse string with xml response. It is ready to send to
	 *         client.
	 * */
	public static void doStoreChatMessage(SetiChatMessage setiChatMessage) {
		// Pending Message Entity with default serial key
		Entity pendingMessage = new Entity(
				DataModelConstants.DS_ENTITY_PENDIGMESSAGE,
				System.currentTimeMillis());
		// Propieties pending Message
		// IdMessage of the stored message
		pendingMessage.setProperty(
				DataModelConstants.DS_PROPERTY_PENDIGMESSAGE_IDDESTINATION,
				setiChatMessage.getHeader().getIdDestination());
		// Message to Text
		Text scMessageText = new Text(
				XmppReceiverServlet.setiChatMessageFactory
						.createXmlString(setiChatMessage));
		// Stored message
		pendingMessage.setProperty(
				DataModelConstants.DS_PROPERTY_PENDIGMESSAGE_MESSAGE,
				scMessageText);
		// stored in datastore
		XmppReceiverServlet.datastore.put(pendingMessage);
	}

	/**
	 * Method to make a response to upload message.
	 * 
	 * @param setiChatMessage
	 *            message received to be processed
	 * @return scXmlResponse string with xml response. It is ready to send to
	 *         client.
	 * */
	public static String doUploadMessage(SetiChatMessage setiChatMessage) {
		String typeCert = setiChatMessage.getContent().getUpload().getType();
		String certificate = setiChatMessage.getContent().getUpload()
				.getCertificate();
		String user = setiChatMessage.getHeader().getIdSource();
		String scXmlResponse = new String();
		if (!SecurityManager.hasCertificate(user, typeCert)) {
			SecurityManager.putCertificate(user, typeCert, certificate);
			SetiChatMessageFactory scMessageResponse = new SetiChatMessageFactory();
			scXmlResponse = scMessageResponse.createSetiChatMessageResponse(
					GeneralConstants.SELF, setiChatMessage.getHeader()
							.getIdSource(), setiChatMessage.getHeader()
							.getIdMessage(), String
							.valueOf(MessageTypeConstants.TYPE_UPLOAD),
					setiChatMessage.getHeader().isEncrypted(), setiChatMessage
							.getHeader().isSigned(),
					ResponseMessageConstants.RESPONSE_CODE_UPLOAD_OK,
					ResponseMessageConstants.RESPONSE_MESSAGE_UPLOAD_OK);
		} else {
			scXmlResponse = doRevocationMessage(setiChatMessage);
		}
		return scXmlResponse;
	}

	// /**
	// * Method to check a message with its schema.
	// *
	// * @param messageXML
	// * String of the xml message to check.
	// * @return true or false if messageXml is a well format message.
	// * @throws IOException
	// * */
	// public static boolean isSetiChatMessageFormat(String messageXml) throws
	// IOException {
	// log.warning(messageXml + "=" + messageXml.getBytes());
	// boolean isSetiChatMessageFormat = false;
	// try {
	// // XML standard Schema language
	// log.warning("1");
	// SchemaFactory factory = SchemaFactory
	// .newInstance("http://www.w3.org/2001/XMLSchema");
	// // Schema to java object.
	// log.warning("2");
	// Schema schema = factory.newSchema(new URL(
	// GeneralConstants.SETICHATSCHEMA));
	// // Create a validator from the schema.
	// log.warning("3");
	// Validator validator = schema.newValidator();
	// // Validate message.
	// log.warning("4");
	// validator.validate(new StreamSource(new ByteArrayInputStream(
	// messageXml.getBytes())));
	// log.warning("5");
	// isSetiChatMessageFormat = true;
	// } catch (SAXException ex) {
	// log.warning("XML not valid because " + ex.getMessage());
	// isSetiChatMessageFormat = false;
	// } catch (IOException e) {
	// log.warning("IOException in XMLParser.validateXML()");
	// isSetiChatMessageFormat = false;
	// }
	//
	// return isSetiChatMessageFormat;
	// }

	/**
	 * Method to get a email from a JID.
	 * 
	 * @param JID
	 *            XMPP user reference.
	 * @return String with the email of the JID.
	 * */
	public static String getEmail(JID jid) {
		return jid.getId().substring(0, jid.getId().indexOf("/"));
	}

	/**
	 * Method to get a user mobile email.
	 * 
	 * @param mobile
	 *            mobile user that gets the email.
	 * @return email of user.
	 * */
	public static String getIdGoogle(String mobile) {
		String idGoogle = new String();
		Query queryUser = new Query(DataModelConstants.DS_ENTITY_USER);
		queryUser.addFilter(DataModelConstants.DS_PROPERTY_USER_MOBILE,
				Query.FilterOperator.EQUAL, mobile);
		PreparedQuery pq = XmppReceiverServlet.datastore.prepare(queryUser);
		for (Entity result : pq.asIterable()) {
			idGoogle = result.getKey().toString();
		}
		if (!idGoogle.isEmpty()) {
			idGoogle = idGoogle.split("\"")[1];
		}
		return idGoogle;
	}

	/**
	 * Method to check mobile and email are the same user.
	 * 
	 * @param msg
	 *            XMPP message with a google ID
	 * @param scMsg
	 *            SetiChatMessage with a email.
	 * @return false if mobile and email are the same user. true if not.
	 */
	public static boolean idsSourceNotMatch(Message msg, SetiChatMessage scMsg) {
		return idsSourceNotMatch(ServerActions.getEmail(msg.getFromJid()),
				scMsg.getHeader().getIdSource());
	}

	/**
	 * Method to check mobile and email are the same user.
	 * 
	 * @param email
	 *            ID source from XMPP message
	 * @param mobile
	 *            ID source from SetiChatMessage.
	 * @return false if mobile and email are the same user. true if not.
	 */
	public static boolean idsSourceNotMatch(String email, String mobile) {
		boolean idsSourceNotMatch = false;
		if (email.compareToIgnoreCase(getIdGoogle(mobile)) != 0) {
			idsSourceNotMatch = true;
		}

		return idsSourceNotMatch;
	}

	/**
	 * User available to send setiChatMessage
	 * 
	 * @param setiChatMessage
	 *            message to send
	 * */
	public static boolean isDstAvailable(SetiChatMessage setiChatMessage) {
		JID idDestination = new JID(ServerActions.getIdGoogle(setiChatMessage
				.getHeader().getIdDestination()));
		boolean isAvailable = true;
		if (setiChatMessage.getHeader().getIdDestination()
				.compareToIgnoreCase(GeneralConstants.SELF) != 0) {
			isAvailable = XmppReceiverServlet.xmppService.getPresence(
					idDestination).isAvailable();
		}

		return isAvailable;
	}

	/**
	 * User available to send setiChatMessage
	 * 
	 * @param setiChatMessage
	 *            message to send
	 * */
	public static boolean isSrcAvailable(Message message) {
		return XmppReceiverServlet.xmppService
				.getPresence(message.getFromJid()).isAvailable();
	}

	/**
	 * XMPP Message reply
	 * 
	 * @param message
	 *            XMPP message received. It is used to get source information.
	 * @param body
	 *            Setichat message to send.
	 * */
	public static void replyToMessage(Message message, String body) {
		Message reply = new MessageBuilder()
				.withRecipientJids(message.getFromJid())
				.withMessageType(MessageType.CHAT).withBody(body).build();
		XmppReceiverServlet.xmppService.sendMessage(reply);
	}

	/**
	 * XMPP Message send
	 * 
	 * @param setiChatMessage
	 *            ready to transmit.
	 * */
	public static void sendToMessage(SetiChatMessage setiChatMessage) {
		String idGoogle = getIdGoogle(setiChatMessage.getHeader()
				.getIdDestination());
		Message message = new MessageBuilder()
				.withRecipientJids(new JID(idGoogle))
				.withMessageType(MessageType.CHAT)
				.withBody(
						XmppReceiverServlet.setiChatMessageFactory
								.createXmlString(setiChatMessage)).build();
		XmppReceiverServlet.xmppService.sendMessage(message);
	}

	/**
	 * Generate Id message
	 * */
	public static String generateRandomID() {
		String id = new String();
		Random rand = new Random(System.currentTimeMillis());
		int aux;
		for (int i = 0; i < 32; i++) {
			aux = rand.nextInt(16);
			switch (aux) {
			case 10:
				id += "a";
				break;
			case 11:
				id += "b";
				break;
			case 12:
				id += "c";
				break;
			case 13:
				id += "d";
				break;
			case 14:
				id += "e";
				break;
			case 15:
				id += "f";
				break;
			default:
				id += String.valueOf(aux);
				break;

			}
		}
		return id;
	}
}
